package com.snow.storeapi.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.snow.storeapi.entity.Diagnosis;
import com.snow.storeapi.mapper.DiagnosisMapper;
import com.snow.storeapi.service.IDiagnosisService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;

@Service
public class DiagnosisServiceImpl extends ServiceImpl<DiagnosisMapper, Diagnosis> implements IDiagnosisService {

    @Autowired
    private DiagnosisMapper diagnosisMapper;

    @Override
    public List<Diagnosis> generate(Map record) {
        String uuid = (String) record.get("_id");
        List<Diagnosis> resList = new ArrayList<>();
        Diagnosis diagnosis;
        List<Map<String, Object>> formulaCatalog = diagnosisMapper.selectFormulaCatalog();
        Map<String, Object> diagnosisResult = new HashMap<>();
        String diagnoseID = ((Map<String, String>) record.get("patientInfo")).get("id");
        List<Map<String, Object>> chiefComplaint = (List<Map<String, Object>>)((Map) record.get("chiefComplaint")).get("data");
        List<Map<String, Object>> unusualData = (List<Map<String, Object>>)((Map) record.get("checkout")).get("checked");
        //List<Map<String, Object>> unusualData = (List<Map<String, Object>>) unusual.get("data");
        Map<String, String> chiefContent = new HashMap<>();
        List<String> list;
        // 重组主诉
        for (Map<String, Object> item : chiefComplaint) {
            list = new ArrayList();
            //if (item.get("part") != null && ((List) item.get("part")).size() > 0) {
            //    trimAdd(((List) item.get("part")).get(0), list);
            //}
            //trimAdd(item.get("symptom"), list);
            //trimAdd(item.get("character"), list);
            //trimAdd(item.get("level"), list);
            //trimAdd(item.get("unit"), list);
            //chiefContent.put(String.join("@", list), String.valueOf(item.get("time")));
            if (item.get("part") != null && ((List) item.get("part")).size() > 0) {
            	for(int j=0;j<((List) item.get("part")).size();j++)
				{
					trimAdd(((List) item.get("part")).get(j), list);
		            trimAdd(item.get("symptom"), list);
		            //trimAdd(item.get("character"), list);
		            trimAdd("C.102.100000", list);
		            trimAdd(item.get("level"), list);
		            trimAdd(item.get("unit"), list);
		            chiefContent.put(String.join("@", list), String.valueOf(item.get("time")));					
				}
            }            
        }
        Map<String, Map<String, Object>> checkContent = new HashMap();
        Map<String, Object> temp = new HashMap();
        // 重组检查检验
        for (Map<String, Object> data : unusualData) {
        	for (Map<String, Object> item : (List<Map<String, Object>>)data.get("data")) {
        		temp = new HashMap();
        		temp.put("resultValue", item.get("resultValue"));
        		temp.put("resultUnit", item.get("resultUnit"));
        		checkContent.put((String) item.get("itemCode"), temp);
        	}
        }
        //支持重复诊断判断,清除原有计算结果
        diagnosisMapper.deleteDiagnosisData(diagnoseID);
        diagnosisMapper.deleteDiagnosisResult(diagnoseID);  
        BigDecimal zero = new BigDecimal("0");
        BigDecimal one = new BigDecimal("1");
        for (int i = 0; i < formulaCatalog.size(); i++) {
            Map<String, Object> mapTotal = (Map) formulaCatalog.get(i);
            String formulaCode = String.valueOf(mapTotal.get("LEVEL_CODE"));
            String formulaName = String.valueOf(mapTotal.get("LEVEL_NAME"));
            String formulaRink = String.valueOf(mapTotal.get("FORMULA_RINK"));
            String diseaseCode = String.valueOf(mapTotal.get("DISEASE_CODE"));
            String diseaseName = String.valueOf(mapTotal.get("DISEASE_NAME"));
            BigDecimal itemModulus = (BigDecimal) mapTotal.get("ITEM_MODULUS");
            //String caseModulus = String.valueOf(mapTotal.get("CASE_MODULUS"));
            BigDecimal caseModulus = (BigDecimal) mapTotal.get("CASE_MODULUS");
            String caseMinRate = String.valueOf(mapTotal.get("CASE_MINRATE"));
            String caseMaxRate = String.valueOf(mapTotal.get("CASE_MAXRATE"));
            //String caseAmount = String.valueOf(mapTotal.get("CASE_AMOUNT"));
            BigDecimal caseAmount = new BigDecimal((Integer) mapTotal.get("CASE_AMOUNT"));
            //String caseFAmount = String.valueOf(mapTotal.get("CASE_FAMOUNT"));
            BigDecimal caseFAmount = new BigDecimal((Integer) mapTotal.get("CASE_FAMOUNT"));
            String resultLevelCode="",resultLevelName="",resultLevelValue="";
            BigDecimal caseFRate = new BigDecimal("0");
            //根据相似病例算出病历相似权重占比
            System.out.println("caseFAmount:"+caseFAmount);
            System.out.println("caseAmount:"+caseAmount);
            if(caseModulus.compareTo(zero)>0 && caseFAmount.compareTo(caseAmount)<0)
                //caseFRate=String.valueOf(Double.parseDouble(caseFAmount)/Double.parseDouble(caseAmount));
            	caseFRate=caseFAmount.divide(caseAmount,2,BigDecimal.ROUND_HALF_DOWN);
            else
                caseFRate=caseModulus;
            BigDecimal itemFRate = new BigDecimal("0");
            int rinkScore=0;
            List<Map<String, Object>> diagnosisDatas= new ArrayList<>();
            //根据某个公式中配置代码获取对应公式下所有诊断指标信息
            List<Map<String, Object>> formulaContent = diagnosisMapper.selectFormulaContent(formulaCode);
            String[][] itemContent = new String[formulaContent.size()][2];
            for (int j = 0; j < formulaContent.size(); j++) {
                Map<String, Object> mapDetail = formulaContent.get(j);
                String titleName = (String) mapDetail.get("TITLE_NAME");
                String showID = (String) mapDetail.get("SHOW_ID");
                String showName = (String) mapDetail.get("SHOW_NAME");
                String indexType = (String) mapDetail.get("INDEX_TYPE");
                String impType = (String) mapDetail.get("IMP_TYPE");
                String rinkType = (String) (mapDetail.get("RINK_TYPE"));
                String calMethod = (String) mapDetail.get("CAL_METHOD");
                String calScore = (String) mapDetail.get("CAL_SCORE");
                BigDecimal addModulus = (BigDecimal) mapDetail.get("ADD_MODULUS");
                String showUit = (String) mapDetail.get("SHOW_UNIT");
                String orderNo = (String) mapDetail.get("ORDER_NO");
                BigDecimal itemScore = new BigDecimal(0);
                String itemValue="",partCode="",showContent="";
                if("C".equals(indexType))
                {
                	showContent=showID.substring(showID.indexOf("@"),showID.length());
	                partCode=showID.substring(0,showID.indexOf("@"));
	                String[] partValue=partCode.split(",");
	                for(int k=0;k<partValue.length;k++)
	                {
	                	showID=partValue[k]+showContent;
	                	if(chiefContent.get(showID) != null) {
	                		itemValue = chiefContent.get(showID);
	                		break;
	                	}
	                }
            	}else if("D".equals(indexType) && chiefContent.get(showID) != null) {
                	itemValue = chiefContent.get(showID);
            	}else if(indexType.indexOf("G.")>=0 && checkContent.get(showID) != null) {
                    itemValue = String.valueOf(checkContent.get(showID).get("resultValue"));
                }
                if(itemValue==null || "".equals(itemValue)) itemValue="0";
                //根据病历文件信息，生成每个判断指标的加权结果
                if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "1".equals(calMethod) && calScore.indexOf("$")<0 && Double.parseDouble(itemValue)==Double.parseDouble(calScore)){
                    itemScore = addModulus;
                }else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "3".equals(calMethod) && calScore.indexOf("$")<0 && Double.parseDouble(itemValue)>=Double.parseDouble(calScore)){
                    itemScore = addModulus;
                }else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "4".equals(calMethod) && calScore.indexOf("$")<0 && Double.parseDouble(itemValue)<=Double.parseDouble(calScore)){
                    itemScore = addModulus;
                }else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "5".equals(calMethod) && calScore.indexOf("$")<0 && Double.parseDouble(itemValue)>Double.parseDouble(calScore)){
                    itemScore = addModulus;
                }else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "6".equals(calMethod) && calScore.indexOf("$")<0 && Double.parseDouble(itemValue)<Double.parseDouble(calScore)){
                    itemScore = addModulus;
                }else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "7".equals(calMethod) && calScore.indexOf("$")>=0 && Double.parseDouble(calScore.substring(0,calScore.indexOf("$")))<=Double.parseDouble(itemValue) && Double.parseDouble(calScore.substring(calScore.indexOf("$")+1,calScore.length()))>=Double.parseDouble(itemValue)){
                    itemScore = addModulus;
                }
		    	//指标优先级判断得分
				if("1".equals(rinkType) && itemScore.compareTo(zero)>0) {//指标参与计算过程,并指标得分为100%
					itemScore = new BigDecimal(1);
				}else if("3".equals(rinkType) && itemScore.compareTo(zero)>0) {//指标不参与计算过程，指标得分为0%
					itemScore = new BigDecimal(0);
				}     
		    	//诊断指标重新赋值
		    	itemContent[j][0]=String.valueOf(mapDetail.get("INDEX_ID"));
		    	itemContent[j][1]=itemValue;				
                //判断本次诊断疾病对应概率
                itemFRate = itemFRate.add(itemScore);
                //插入本次诊断疾病结果的每个指标信息
                String tradeTime=LocalDate.now().toString() + " " + LocalTime.now().toString();
                tradeTime = tradeTime.substring(0,19);
                Map<String, Object> diagnosisData = new HashMap<>();
                if(itemScore.compareTo(zero)>0) {
                    //指标结果值大于零符合插入要求
                    diagnosisData.put("uuid", uuid);
                    diagnosisData.put("diagnoseID", diagnoseID);
                    diagnosisData.put("formulaCode", formulaCode);
                    diagnosisData.put("formulaName", formulaName);
                    diagnosisData.put("indexType", indexType);
                    diagnosisData.put("rinkType", rinkType);
                    diagnosisData.put("showID", showID);
                    diagnosisData.put("showName", showName);
                    diagnosisData.put("itemValue", itemValue);
                    diagnosisData.put("addModulus", addModulus.toString());
                    diagnosisData.put("showUit", showUit);
                    diagnosisData.put("orderNo", orderNo);
                    diagnosisData.put("itemScore", itemScore.toString());
                    diagnosisData.put("calMethod", calMethod);
                    diagnosisData.put("calScore", calScore);
                    diagnosisData.put("tradeTime", tradeTime);

                    diagnosisDatas.add(diagnosisData);
                }
            }
            List<Map<String, Object>> formulaStandard = diagnosisMapper.selectFormulaStandard(formulaCode);
            for (int j = 0; j < formulaStandard.size(); j++) {
                Map<String, Object> mapStandard = formulaStandard.get(j);
                String titleName = (String) mapStandard.get("TITLE_NAME");
				String levelCode = (String) mapStandard.get("LEVEL_CODE");
				String levelName = (String) mapStandard.get("LEVEL_NAME");
				String itemCode = (String) mapStandard.get("ITEM_CODE");
				String itemName = (String) mapStandard.get("ITEM_NAME");
				String calMethod = (String) mapStandard.get("CAL_METHOD");
				String calScore = (String) mapStandard.get("CAL_SCORE");  
				BigDecimal itemScore = new BigDecimal(0);
				String itemValue = "0";
				//根据每个对应指标唯一编号获取对应的值
				for(int k=0;k<itemContent.length;k++)
				{
					if(itemCode.equals(itemContent[k][0]))
					{
						itemValue=itemContent[k][1];
						break;
					}
				}
				//根据病历文件信息，生成每个疾病程度判断指标对应结果
		    	if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "1".equals(calMethod) && calScore.indexOf("@")<0 && Double.parseDouble(itemValue)==Double.parseDouble(calScore)){
		    		itemScore=new BigDecimal(1);
		    	}else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "3".equals(calMethod) && calScore.indexOf("@")<0 && Double.parseDouble(itemValue)>=Double.parseDouble(calScore)){
		    		itemScore=new BigDecimal(1);
		    	}else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "4".equals(calMethod) && calScore.indexOf("@")<0 && Double.parseDouble(itemValue)<=Double.parseDouble(calScore)){
		    		itemScore=new BigDecimal(1);
		    	}else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "5".equals(calMethod) && calScore.indexOf("@")<0 && Double.parseDouble(itemValue)>Double.parseDouble(calScore)){
		    		itemScore=new BigDecimal(1);	
		    	}else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "6".equals(calMethod) && calScore.indexOf("@")<0 && Double.parseDouble(itemValue)<Double.parseDouble(calScore)){
		    		itemScore=new BigDecimal(1);	    		
		    	}else if(!"".equals(calScore) && Double.parseDouble(itemValue)>0 && "7".equals(calMethod) && calScore.indexOf("@")>=0 && Double.parseDouble(calScore.substring(0,calScore.indexOf("@")))<=Double.parseDouble(itemValue) && Double.parseDouble(calScore.substring(calScore.indexOf("@")+1,calScore.length()))>=Double.parseDouble(itemValue)){
		    		itemScore=new BigDecimal(1);	    		
		    	}
		    	//判断本次疾病程度对应结果
		    	if("5".equals(levelCode)) { 
		    		resultLevelValue=resultLevelValue+levelCode+itemScore;
				}else if("4".equals(levelCode)){
					resultLevelValue=resultLevelValue+levelCode+itemScore;
		    	}else if("3".equals(levelCode)){
		    		resultLevelValue=resultLevelValue+levelCode+itemScore;
		    	}else if("2".equals(levelCode)){
		    		resultLevelValue=resultLevelValue+levelCode+itemScore;
		    	}else if("1".equals(levelCode)){
		    		resultLevelValue=resultLevelValue+levelCode+itemScore;
		    	}	
                //插入本次诊断疾病结果的每个指标信息
	            String tradeTime=LocalDate.now().toString() + " " + LocalTime.now().toString();
	            tradeTime = tradeTime.substring(0,19);
                Map<String, Object> diagnosisStandard = new HashMap<>();
                if(itemScore.compareTo(zero)>0) {
                    diagnosisStandard.put("uuid", uuid);
                    diagnosisStandard.put("diagnoseID", diagnoseID);
                    diagnosisStandard.put("formulaCode", formulaCode);
                    diagnosisStandard.put("formulaName", formulaName);
                    diagnosisStandard.put("indexType", "Z");
                    diagnosisStandard.put("rinkType", "");
                    diagnosisStandard.put("showID", itemCode);
                    diagnosisStandard.put("showName", itemName);
                    diagnosisStandard.put("itemValue", itemValue);
                    diagnosisStandard.put("addModulus", levelName);
                    diagnosisStandard.put("showUit", "");
                    diagnosisStandard.put("orderNo", levelCode);
                    diagnosisStandard.put("itemScore", itemScore.toString());
                    diagnosisStandard.put("calMethod", calMethod);
                    diagnosisStandard.put("calScore", calScore);
                    diagnosisStandard.put("tradeTime", tradeTime);
                    diagnosisDatas.add(diagnosisStandard);
                }
            }
			//诊断最终结果按指标要求调整
			//double calRate=Double.parseDouble(itemModulus.toString())*Double.parseDouble(itemFRate.toString())+Double.parseDouble(caseModulus)*Double.parseDouble(caseFRate.toString());
			//double resultRate=0.0;
            BigDecimal calRate = new BigDecimal(0);
            calRate=itemModulus.multiply(itemFRate).add(caseModulus.multiply(caseFRate));
			BigDecimal resultRate = new BigDecimal(0);
			if("1".equals(formulaRink) && calRate.compareTo(zero)>0) resultRate=new BigDecimal(1);
			else if("2".equals(formulaRink) && calRate.compareTo(one)==0) resultRate=new BigDecimal(1);
			else if("2".equals(formulaRink) && calRate.compareTo(one)<0) resultRate=new BigDecimal(0);
			else if("3".equals(formulaRink) && calRate.compareTo(one)>0) resultRate=new BigDecimal(1);
			else resultRate=calRate;
			//诊断疾病程度按指标要求判断
			//System.out.println("resultLevelValue:"+resultLevelValue);
			if(resultLevelValue.indexOf("5")>=0 && resultLevelValue.indexOf("50")<0) {
				resultLevelCode="5";
				resultLevelName="晚期症状";
			}else if(resultLevelValue.indexOf("4")>=0 && resultLevelValue.indexOf("40")<0) {
				resultLevelCode="4";
				resultLevelName="后期症状";				
			}else if(resultLevelValue.indexOf("3")>=0 && resultLevelValue.indexOf("30")<0) {
				resultLevelCode="3";
				resultLevelName="中期症状";				
			}else if(resultLevelValue.indexOf("2")>=0 && resultLevelValue.indexOf("20")<0) {
				resultLevelCode="2";
				resultLevelName="早期症状";				
			}else if(resultLevelValue.indexOf("1")>=0 && resultLevelValue.indexOf("10")<0) {
				resultLevelCode="1";
				resultLevelName="初期症状";				
			}      
			//System.out.println("resultLevelCode:"+resultLevelCode);
			//System.out.println("resultLevelName:"+resultLevelName);			
            //根据本次诊断指标汇总结果，生成本次诊断疾病最终结果
            String tradeTime=LocalDate.now().toString() + " " + LocalTime.now().toString();
            tradeTime = tradeTime.substring(0,19);
            diagnosisResult.put("uuid", uuid);
            diagnosisResult.put("diagnoseID", diagnoseID);
            diagnosisResult.put("formulaCode", formulaCode);
            diagnosisResult.put("formulaName", formulaName);
            diagnosisResult.put("levelCode", resultLevelCode);
            diagnosisResult.put("levelName", resultLevelName);            
            diagnosisResult.put("formulaRink", formulaRink);
            diagnosisResult.put("diseaseCode", diseaseCode);
            diagnosisResult.put("diseaseName", diseaseName);
            diagnosisResult.put("itemModulus", itemModulus);
            diagnosisResult.put("caseModulus", caseModulus);
            diagnosisResult.put("caseMinRate", caseMinRate);
            diagnosisResult.put("caseMaxRate", caseMaxRate);
            diagnosisResult.put("caseAmount", caseAmount);
            diagnosisResult.put("caseFAmount", caseFAmount);
            diagnosisResult.put("itemFRate", itemFRate);
            diagnosisResult.put("caseFRate", caseFRate);
            diagnosisResult.put("resultRate", resultRate);
            diagnosisResult.put("remark", calRate);
            diagnosisResult.put("tradeTime", tradeTime);

            if (diagnosisDatas.size() > 0) {
                diagnosisMapper.insertDiagnosisData(diagnosisDatas);
                diagnosisMapper.insertDiagnosisResult(diagnosisResult);
            }

            diagnosis = new Diagnosis();
            diagnosis.setDiseaseCode(diseaseCode);
            diagnosis.setDiseaseName(diseaseName);
            diagnosis.setItemResult(resultRate.setScale(2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
            diagnosis.setLevelCode(resultLevelCode);
            diagnosis.setLevelName(resultLevelName);
            if (diagnosis.getItemResult().compareTo(zero) == 1) {
                resList.add(diagnosis);
            }
        }
        Collections.sort(resList, new Comparator<Diagnosis>() {
            @Override
            public int compare(Diagnosis o1, Diagnosis o2) {
                if (o1.getItemResult().compareTo(o2.getItemResult()) == 1) {
                    return -1;
                } else {
                    return 1;
                }
            }
        });
        return resList;
    }
    public void trimAdd(Object val, List<String> list) {
        if (val != null && !"".equals(val)) {
            list.add(String.valueOf(val));
        }
    }

    public List<String> findSimilarity(String startRange, String endRange, String diseaseCode, String resultId) {
        return diagnosisMapper.findSimilarity(startRange, endRange, diseaseCode, resultId);
    }
}
